package utils

import (
	"crypto/rand"
	"crypto/sha256"
	"encoding/hex"
	"errors"
	"fmt"

	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt/v4"
	"good.house/config"
	"good.house/internal/constan"
)

// 从context上获取配置信息
func GetConfigByGinContext(ctx *gin.Context) *config.Config {
	value, exists := ctx.Get(constan.CfgKey)

	if !exists {
		return nil
	}

	cfg, ok := value.(*config.Config)

	if !ok {
		return nil
	} else {
		return cfg
	}
}

// 密码哈希方法
func HashPassowrd(val string, salt string) string {
	hash := sha256.New()
	hash.Write([]byte(val))
	hash.Write([]byte(salt))
	return hex.EncodeToString(hash.Sum(nil))
}

// 生成随机盐值
func GenerateSalt(length int) (string, error) {
	slatbyte := make([]byte, length)
	_, err := rand.Read(slatbyte)

	if err != nil {
		return "", err
	}

	return hex.EncodeToString(slatbyte), nil
}

// token校验
func ValidateToken(tokenString string, secretKey string) (*jwt.Token, error) {
	// 解析 token
	token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
		// 验证签名算法
		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
		}
		return []byte(secretKey), nil
	})

	if err != nil {
		return nil, err
	}

	// 验证 token 是否有效
	if !token.Valid {
		return nil, errors.New("invalid token")
	}

	return token, nil
}
